<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
</head>

<body>
	<div id="app">
	</div>

	<script>
		//console.log("begin")
		//setTimeout(()=>{
		//	console.log("settimeout")
		//},0)
		//Promise3.resolve().then(function(){
		//	console.log("Promise3")
		//})
		//console.log("end")
		function Promise3(callback) {
			var self = this;
			self.status = 'PENDING'; // Promise3当前的状态
			self.data = undefined; // Promise3的值
			self.onResolvedCallback = []; // Promise3 resolve时的回调函数集
			self.onRejectedCallback = []; // Promise3 reject时的回调函数集
			callback(resolve, reject); // 执行executor并传入相应的参数

			function resolve(value) {
				if (self.status == 'PENDING') {
					self.status = 'FULFILLED';
					self.data = value;
					// 依次执行成功之后的函数栈
					for (var i = 0; i < self.onResolvedCallback.length; i++) {
						self.onResolvedCallback[i](value);
					}
					// self.then()
				}
			}

			function reject(error) {
				if (self.status === 'PENDING') {
					self.status = 'REJECTED';
					self.data = error;
					// 依次执行失败之后的函数栈
					for (var i = 0; i < self.onRejectedCallback.length; i++) {
						self.onRejectedCallback[i](error);
					}
				}
			}
		}

		Promise3.prototype.then = function (onResolved, onRejected) {
			var self = this;
			var Promise32;

			// 根据标准，如果then的参数不是function，则我们需要忽略它，此处以如下方式处理
			onResolved = typeof onResolved === 'function' ? onResolved : function (value) { };
			onRejected = typeof onRejected === 'function' ? onRejected : function (reason) { };
			// console.log(self.status)
			if (self.status === 'FULFILLED') {
				// 如果Promise31(此处即为this/self)的状态已经确定并且是resolved，我们调用onResolved
				// 因为考虑到有可能throw，所以我们将其包在try/catch块里
				return (Promise32 = new Promise3(function (resolve, reject) {
					try {
						var x = setTimeout(() => {
							onResolved(self.data)
						}, 0);;
						if (x instanceof Promise3) {
							// 如果onResolved的返回值是一个Promise3对象，直接取它的结果做为Promise32的结果
							x.then(resolve, reject);
						}
						resolve(x); // 否则，以它的返回值做为Promise32的结果
					} catch (e) {
						reject(e); // 如果出错，以捕获到的错误做为Promise32的结果
					}
				}));
			}

			// 此处与前一个if块的逻辑几乎相同，区别在于所调用的是onRejected函数，就不再做过多解释
			if (self.status === 'REJECTED') {
				return (Promise32 = new Promise3(function (resolve, reject) {
					try {
						var x = onRejected(self.data);
						if (x instanceof Promise3) {
							x.then(resolve, reject);
						}
					} catch (e) {
						reject(e);
					}
				}));
			}

			if (self.status === 'PENDING') {
				// 如果当前的Promise3还处于pending状态，我们并不能确定调用onResolved还是onRejected，
				// 只能等到Promise3的状态确定后，才能确实如何处理。
				// 所以我们需要把我们的**两种情况**的处理逻辑做为callback放入Promise31(此处即this/self)的回调数组里
				// 逻辑本身跟第一个if块内的几乎一致，此处不做过多解释
				return (Promise32 = new Promise3(function (resolve, reject) {
					self.onResolvedCallback.push(function (value) {
						try {
							var x = onResolved(self.data);
							if (x instanceof Promise3) {
								x.then(resolve, reject);
							}
							resolve(x); // 否则，以它的返回值做为Promise32的结果
						} catch (e) {
							reject(e);
						}
					});

					self.onRejectedCallback.push(function (reason) {
						try {
							var x = onRejected(self.data);
							if (x instanceof Promise3) {
								x.then(resolve, reject);
							}
						} catch (e) {
							reject(e);
						}
					});
				}));
			}
		};

		// 为了下文方便，我们顺便实现一个catch方法
		// Promise3.prototype.catch = function (onRejected) {
		// 	return this.then(null, onRejected);
		// };

		// let p = new Promise3(function (resolve, reject) {
		// 	resolve()
		// 	console.log('2222');
		// });
		// p.then(function(res) {
		// 	console.log('1111');
		// })
		// console.log('3333')
		// console.dir(Promise)
	</script>
</body>

</html>
